use std::time::Duration;

use anyhow::{anyhow, Result};
use hmac::{digest::KeyInit, Hmac};
use jwt::{SigningAlgorithm, ToBase64};
use serde_json::json;
use sha2::Sha256;

#[tauri::command]
pub fn create_jwt_token() -> Result<String, String> {
    let expire = Duration::from_secs(360000);
    let api_key = "8085eca8a19274e3db458993ca6a168c.1ARsgcBw1yu6v3ew";
    let sp = api_key.split('.').collect::<Vec<_>>();
    let api_key = *sp
        .first()
        .ok_or_else(|| anyhow!("Invalid API key"))
        .map_err(|err| err.to_string())?;
    let secret = *sp
        .last()
        .ok_or_else(|| anyhow!("Invalid API key"))
        .map_err(|err| err.to_string())?;

    let now = std::time::SystemTime::now().duration_since(std::time::UNIX_EPOCH);
    let now = now.map_err(|err| err.to_string())?;

    let exp = now + expire;

    let now_ts = now.as_millis();
    let exp_ts = exp.as_millis();

    let key: Hmac<Sha256> =
        Hmac::new_from_slice(secret.as_bytes()).map_err(|err| err.to_string())?;
    let header = json!(
        {"alg":"HS256","sign_type":"SIGN","typ":"JWT"}
    );

    let claims = json!({
        "api_key" : api_key,
        "exp" : exp_ts,
        "timestamp":now_ts
    });
    let header = header.to_base64().map_err(|err| err.to_string())?;
    let claims = claims.to_base64().map_err(|err| err.to_string())?;
    let signature = key.sign(&header, &claims).map_err(|err| err.to_string())?;

    let token_string = [&*header, &*claims, &signature].join(".");
    Ok(token_string)
}
